home *** CD-ROM | disk | FTP | other *** search
/ Aminet 7 / Aminet 7 - August 1995.iso / Aminet / comm / tcp / AmigaTCP.lha / AmigaTCP / src / cmdparse.c < prev    next >
C/C++ Source or Header  |  1989-06-24  |  3KB  |  141 lines

  1. /* Parse command line, set up command arguments Unix-style, and call function.
  2.  * Note: argument is modified (delimiters are overwritten with nulls)
  3.  * Improved error handling by Brian Boesch of Stanford University
  4.  */
  5. #ifdef TRACE
  6. #include <stdio.h>
  7. #include "machdep.h"
  8. #include "trace.h"
  9. #endif
  10.  
  11. #include "cmdparse.h"
  12.  
  13. int
  14. cmdparse(cmds,line)
  15. struct cmds cmds[];
  16. register char *line;
  17. {
  18.     struct cmds *cmdp;
  19.     char *argv[NARG],*cp,*index();
  20.     int argc,qflag;
  21.     int i, rslt;
  22.  
  23.     /* Remove cr/lf */
  24.     if((cp = index(line,'\r')) != NULLCHAR)
  25.         *cp = '\0';
  26.     if((cp = index(line,'\n')) != NULLCHAR)
  27.         *cp = '\0';    /* shouldn't be necessary */
  28.  
  29.     for(argc = 0;argc < NARG;argc++)
  30.         argv[argc] = NULLCHAR;
  31.  
  32.     for(argc = 0;argc < NARG;){
  33.         qflag = 0;
  34.         /* Skip leading white space */
  35.         while(*line == ' ' || *line == '\t')
  36.             line++;
  37.         if(*line == '\0')
  38.             break;
  39.         /* Check for quoted token */
  40.         if(*line == '"'){
  41.             line++;    /* Suppress quote */
  42.             qflag = 1;
  43.         }
  44.         argv[argc++] = line;    /* Beginning of token */
  45.         /* Find terminating delimiter */
  46.         if(qflag){
  47.             /* Find quote, it must be present */
  48.             if((line = index(line,'"')) == NULLCHAR){
  49.                 return -1;
  50.             }
  51.         } else {
  52.             /* Find space or tab. If not present,
  53.              * then we've already found the last
  54.              * token.
  55.              */
  56.             if((cp = index(line,' ')) == NULLCHAR
  57.              && (cp = index(line,'\t')) == NULLCHAR){
  58.                 break;
  59.             }
  60.             *cp++ = '\0';
  61.             line = cp;
  62.         }
  63.     }
  64. #ifdef TRACE
  65.     if(trace & TRACE_CMDPARSE) {
  66.         printf("Number of tokens = %d\r\n",argc);
  67.         for (i=0; i< argc; i++) {
  68.             printf("Argument=%d  '%s'\r\n",i,argv[i]);
  69.         }
  70.     }
  71. #endif
  72.     if (argc < 1) {        /* empty command line */
  73.         argc = 1;
  74.         argv[0] = "";
  75.     }
  76.     /* Lines beginning with "#" are comments */
  77.     if(argv[0][0] == '#')
  78.         return 0;
  79.  
  80.     /* Look up command in table; prefix matches are OK */
  81.     for(cmdp = cmds;cmdp->name != NULLCHAR;cmdp++){
  82.         if(strncmp(argv[0],cmdp->name,strlen(argv[0])) == 0)
  83.             break;
  84.     }
  85.     if(cmdp->name == NULLCHAR) {
  86.         if(cmdp->argc_errmsg != NULLCHAR) 
  87.             printf("%s\r\n",cmdp->argc_errmsg);
  88.         return -1;
  89.     } else {
  90.         if(argc < cmdp->argcmin) {
  91.             /* Insufficient arguments */
  92.             printf("Usage: %s\r\n",cmdp->argc_errmsg);
  93.             return -1;
  94.         } else {
  95.             rslt = (*cmdp->func)(argc,argv);
  96.             if ((rslt < 0) && (cmdp->exec_errmsg != NULLCHAR))
  97.                 printf("%s\r\n",cmdp->exec_errmsg);
  98.             return(rslt);
  99.         }
  100.     }
  101. }
  102.  
  103. /* Call a subcommand based on the first token in an already-parsed line */
  104. int
  105. subcmd(tab,argc,argv)
  106. struct cmds tab[];
  107. int argc;
  108. char *argv[];
  109. {
  110.     int rslt;
  111.     register struct cmds *cmdp;
  112.  
  113.     /* Strip off first token and pass rest of line to subcommand */
  114.     if (argc < 2) {
  115.         if (argc < 1)
  116.             printf("SUBCMD - Don't know what to do?\r\n");
  117.         else
  118.             printf("\"%s\" - takes at least one argument\r\n",argv[0]);
  119.         return -1;
  120.     }
  121.     argc--;
  122.     argv++;
  123.     for(cmdp = tab;cmdp->name != NULLCHAR;cmdp++){
  124.         if(strncmp(argv[0],cmdp->name,strlen(argv[0])) == 0){
  125.             if(argc < cmdp->argcmin) {
  126.                 if (cmdp->argc_errmsg != NULLCHAR)
  127.                     printf("Usage: %s\r\n",cmdp->argc_errmsg);
  128.                 return -1;
  129.             } else {
  130.                 rslt = (*cmdp->func)(argc,argv);
  131.                 if ((rslt < 0) && (cmdp->exec_errmsg != NULLCHAR))
  132.                     printf("%s\r\n",cmdp->exec_errmsg);
  133.                 return(rslt);
  134.             }
  135.         }
  136.     }
  137.     if (cmdp->argc_errmsg != NULLCHAR) 
  138.         printf("%s\r\n",cmdp->argc_errmsg);
  139.     return -1;
  140. }
  141.